package com.zzyl.service.impl;

import com.zzyl.entity.AlertData;
import com.zzyl.entity.AlertRule;
import com.zzyl.mapper.AlertDataMapper;
import com.zzyl.mapper.AlertRuleMapper;
import com.zzyl.service.AlertTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @Description AlertTaskServiceImpl
 * @Author xulang
 * @Date 2025-09-16
 */
@Service
@Slf4j
public class AlertTaskServiceImpl implements AlertTaskService {

    @Autowired
    private AlertRuleMapper alertRuleMapper;

    @Autowired
    private AlertDataMapper alertDataMapper;


    @Value("${alert.task.time.window:300}") // 默认5分钟时间窗口
    private Integer timeWindow;

    /**
     * 定时执行报警检查任务
     */
    @Override
    public void processAlertTask() {
        log.info("开始执行报警检查任务");
        long startTime = System.currentTimeMillis();

        try {
            // 1. 获取所有启用的报警规则
            List<AlertRule> activeRules = alertRuleMapper.selectActiveRules();
            log.info("获取到 {} 条启用的报警规则", activeRules.size());

            if (activeRules.isEmpty()) {
                log.info("没有启用的报警规则，跳过本次检查");
                return;
            }

            // 2. 遍历每条规则进行检查
            for (AlertRule rule : activeRules) {
                try {
                    processRule(rule);
                } catch (Exception e) {
                    log.error("处理报警规则 {} 时发生错误", rule.getId(), e);
                }
            }

            long endTime = System.currentTimeMillis();
            log.info("报警检查任务执行完成，耗时: {} ms", endTime - startTime);
        } catch (Exception e) {
            log.error("执行报警检查任务时发生错误", e);
        }
    }

    /**
     * 处理单条报警规则
     */
    private void processRule(AlertRule rule) {
        log.debug("开始处理报警规则: {}", rule.getAlertRuleName());

        // 1. 检查是否在沉默期内
        if (isInSilentPeriod(rule)) {
            log.debug("规则 {} 在沉默期内，跳过检查", rule.getAlertRuleName());
            return;
        }

        // 2. 获取设备当前数据（这里需要调用你的设备数据接口）
        String currentValue = getCurrentDeviceValue(rule);
        if (currentValue == null) {
            log.debug("无法获取设备 {} 的当前数据", rule.getDeviceName());
            return;
        }

        // 3. 检查是否满足报警条件
        if (checkAlertCondition(rule, currentValue)) {
            log.info("规则 {} 满足报警条件，当前值: {}", rule.getAlertRuleName(), currentValue);
            // 4. 触发报警
            triggerAlert(rule, currentValue);
        } else {
            log.debug("规则 {} 不满足报警条件", rule.getAlertRuleName());
        }
    }

    /**
     * 检查是否在沉默期内
     */
    private boolean isInSilentPeriod(AlertRule rule) {
        if (rule.getAlertSilentPeriod() == null || rule.getAlertSilentPeriod() <= 0) {
            return false;
        }

        try {
            int alertCount = alertRuleMapper.countAlertsInSilentPeriod(
                    rule.getId(), rule.getAlertSilentPeriod());
            return alertCount > 0;
        } catch (Exception e) {
            log.error("检查沉默期时发生错误，规则ID: {}", rule.getId(), e);
            return false; // 出错时默认不处于沉默期
        }
    }

    /**
     * 获取设备当前数据值
     *
     */
    private String getCurrentDeviceValue(AlertRule rule) {
        try {
            // TODO: 调用你的设备数据接口获取当前值
            // 例如调用 /iot/QueryDevicePropertyStatus 接口
            return getDeviceValueFromAPI(rule);
        } catch (Exception e) {
            log.error("获取设备 {} 数据失败", rule.getDeviceName(), e);
            return null;
        }
    }

    /**
     * 从API获取设备数据
     */
    private String getDeviceValueFromAPI(AlertRule rule) {
        // 示例：调用设备属性状态查询接口
        try {
            // 临时返回模拟值用于测试
            return "45.0";
        } catch (Exception e) {
            log.error("调用设备API失败，设备ID: {}, 功能ID: {}", rule.getIotId(), rule.getFunctionId(), e);
            return null;
        }
    }

    /**
     * 检查是否满足报警条件
     */
    private boolean checkAlertCondition(AlertRule rule, String currentValueStr) {
        if (currentValueStr == null || rule.getValue() == null) {
            return false;
        }

        try {
            // 转换为数值进行比较
            Float currentValue = Float.parseFloat(currentValueStr);
            Float thresholdValue = rule.getValue();

            // 根据比较操作符判断
            switch (rule.getOperator()) {
                case ">":
                    return currentValue > thresholdValue;
                case ">=":
                    return currentValue >= thresholdValue;
                case "<":
                    return currentValue < thresholdValue;
                case "<=":
                    return currentValue <= thresholdValue;
                case "=":
                case "==":
                    return Math.abs(currentValue - thresholdValue) < 0.001;
                default:
                    log.warn("不支持的比较操作符: {}", rule.getOperator());
                    return false;
            }
        } catch (NumberFormatException e) {
            log.warn("无法解析数据值进行比较: ruleId={}, value={}", rule.getId(), currentValueStr);
            return false;
        } catch (Exception e) {
            log.error("检查报警条件时发生错误: ruleId={}", rule.getId(), e);
            return false;
        }
    }

    /**
     * 触发报警
     */
    private void triggerAlert(AlertRule rule, String currentValue) {
        try {
            log.info("触发报警: 规则ID={}, 规则名称={}", rule.getId(), rule.getAlertRuleName());

            // 构建报警数据
            AlertData alertData = new AlertData();
            alertData.setIotId(rule.getIotId());
            alertData.setDeviceName(rule.getDeviceName());
            alertData.setNickname(rule.getDeviceName()); // 临时使用设备名称
            alertData.setProductKey(rule.getProductKey());
            alertData.setProductName(rule.getProductName());
            alertData.setFunctionId(rule.getFunctionId());
            alertData.setAccessLocation("未知位置"); // 需要从设备信息中获取
            alertData.setDataValue(currentValue);
            alertData.setAlertRuleId(rule.getId());
            alertData.setAlertReason(buildAlertReason(rule, currentValue));
            alertData.setType(rule.getAlertDataType() != null ? rule.getAlertDataType() : 1); // 默认设备异常数据
            alertData.setStatus(0); // 待处理
            alertData.setCreateTime(LocalDateTime.now());
            alertData.setDeviceDescription("未知描述"); // 需要从设备信息中获取

            // 保存报警数据
            int result = alertDataMapper.insert(alertData);
            if (result <= 0) {
                log.warn("保存报警数据失败，规则ID: {}", rule.getId());
                return;
            }

            // 发送报警通知
            sendAlertNotification(rule, alertData);

            log.info("报警触发完成，报警数据ID: {}", alertData.getId());

        } catch (Exception e) {
            log.error("触发报警失败，规则ID: {}", rule.getId(), e);
        }
    }

    /**
     * 构建报警原因
     */
    private String buildAlertReason(AlertRule rule, String currentValue) {
        return String.format("%s %s %s",
                rule.getFunctionName(),
                rule.getOperator(),
                rule.getValue());
    }

    /**
     * 发送报警通知
     */
    private void sendAlertNotification(AlertRule rule, AlertData alertData) {
        // TODO: 实现实际的通知逻辑（邮件、短信、微信等）
        log.info("发送报警通知: 规则={}, 当前值={}", rule.getAlertRuleName(), alertData.getDataValue());
    }
}
